package com.alibam.core.wechat.oauth;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.alibam.core.wechat.exception.WeChatException;

public abstract class AbstractOauthFilter implements Filter {

	Logger logger = Logger.getLogger(AbstractOauthFilter.class);

	public static final String OAUTH2HOLDER_SESSION_KEY = "_wechat_oAuth2Holder";

	@Override
	public void doFilter(ServletRequest req, ServletResponse rsp,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) rsp;
		HttpSession session = request.getSession();
		String fullURL = getFullRequestURL(request);
		
		//logger.info("Oauth filter. fullurl : " +  fullURL);
		
		OAuth2Holder oAuth2Holder = (OAuth2Holder) session
				.getAttribute(OAUTH2HOLDER_SESSION_KEY);
		if (oAuth2Holder == null) { // 未访问过
			String code = request.getParameter("code");
			if (code != null) { // 有code， 初始化Oauth2Holder & cache in session
				try {
					oAuth2Holder = new OAuth2Holder(code);
					session.setAttribute(OAUTH2HOLDER_SESSION_KEY, oAuth2Holder);
					onOAuthSuccess(oAuth2Holder.getOAuthUserInfo(), request);
				} catch (WeChatException e) {
					logger.error("OAuth 认证失败，重定向到index页。 请求URL：{" + fullURL
							+ "}， 错误信息：{" + e.getMessage() + "}");
					response.sendRedirect(fullURL.replaceAll("&*?code=.+", ""));
					return;
				}
			} else { // 无code， 说明需要签名后重定向访问。
				fullURL = OAuth2Holder.getOAuthUrl(fullURL,
						OAuth2Holder.OAUTH_SCOPE_SNSAPI_USERINFO);
				logger.info("user redirect to url :{" + fullURL + "}");
				response.sendRedirect(fullURL);
				return;
			}
		} else {
			//logger.info("wechat filter, oauth in session， url is " + fullURL);
		}

		chain.doFilter(request, response);
	}

	protected abstract void onOAuthSuccess(OAuthUserInfo oAuthUserInfo,
			HttpServletRequest request);

	String getFullRequestURL(HttpServletRequest req) {
		String reqParamStr = req.getQueryString();
		reqParamStr = reqParamStr == null ? "" : "?" + reqParamStr;
		return req.getRequestURL().append(reqParamStr).toString();
	}
}
